/**
 * 
 */
package info.niwota.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import jvs.peer.util.Log;
import x.org.apache.http.HttpResponse;
import x.org.apache.http.HttpStatus;
import x.org.apache.http.entity.ContentProducer;
import x.org.apache.http.entity.EntityTemplate;
import x.org.apache.http.entity.StringEntity;
import x.org.apache.http.protocol.BasicHttpContext;
import x.org.apache.http.protocol.HttpContext;

/**
 * @author qiangli
 *
 */
public class HttpServletResponseWrapper implements HttpServletResponse {
	private final HttpResponse res;
	private final BasicHttpContext context;
	private String charset;
	private int contentLength;
	private String contentType;
	
	public HttpServletResponseWrapper(HttpResponse res, HttpContext context) {
		this.res = res;
		this.context = (BasicHttpContext) context;
	}
	
	
	public String getCharacterEncoding() {
		return charset;
	}

	
	public String getContentType() {
		return contentType;
	}

	
	public ServletOutputStream getOutputStream() throws IOException {
//		final ByteArrayOutputStream bout = new ByteArrayOutputStream();
//		final ServletOutputStream sout = new ServletOutputStream() {
//			
//			
//			public void write(byte[] b, int off, int len) throws IOException {
//				bout.write(b, off, len);
//			}
//
//			
//			public void write(byte[] b) throws IOException {
//				bout.write(b);
//			}
//
//			
//			public void write(int b) throws IOException {
//				bout.write(b);
//			}
//		};
//		
//		final EntityTemplate entity = new EntityTemplate(new ContentProducer() {
//			public void writeTo(final OutputStream os) throws IOException {
//				os.write(bout.toByteArray());
//				os.flush();
//			}
//		});
//		entity.setContentType(this.contentType);
//		entity.setContentEncoding(charset);
//		res.setEntity(entity);
//		return sout;
		
		throw new IOException("Use ContentProducer");
	}

	public void sendContent(ContentProducer content) {
		final EntityTemplate entity = new EntityTemplate(content);
		entity.setContentType(this.contentType);
		entity.setContentEncoding(charset);
		res.setEntity(entity);
	}
	
	
	public PrintWriter getWriter() throws IOException {
//		final StringWriter sw = new StringWriter();
//		PrintWriter pw = new PrintWriter(sw);
//		final EntityTemplate entity = new EntityTemplate(new ContentProducer() {
//			public void writeTo(final OutputStream os) throws IOException {
//				Writer w = new OutputStreamWriter(os);
//				w.write(sw.toString());
//				w.flush();
//			}
//		});
//		entity.setContentType(this.contentType);
//		entity.setContentEncoding(charset);
//		res.setEntity(entity);
//		
//		return pw;
		
		throw new IOException("Use ContentProducer");
	}

	
	public void setCharacterEncoding(String charset) {
		this.charset = charset;
	}

	
	public void setContentLength(int len) {
		this.contentLength = len;
	}

	
	public void setContentType(String type) {
		this.contentType = type;
	}

	
	public void setBufferSize(int size) {
	}

	
	public int getBufferSize() {
		return 0;
	}

	
	public void flushBuffer() throws IOException {
		throw new IllegalStateException("TBD");
	}

	
	public void resetBuffer() {
		throw new IllegalStateException("TBD");
	}

	
	public boolean isCommitted() {
		return true;
	}

	
	public void reset() {
		throw new IllegalStateException("TBD");
	}

	
	public void setLocale(Locale loc) {
		res.setLocale(loc);
	}

	
	public Locale getLocale() {
		return res.getLocale();
	}

	
	public void addCookie(Cookie cookie) {
		res.addHeader("Set-Cookie", cookie.toString());
		res.addHeader("Set-Cookie2", cookie.toString());
	}

	
	public boolean containsHeader(String name) {
		return res.containsHeader(name);
	}

	
	public String encodeURL(String url) {
		return url;
	}

	
	public String encodeRedirectURL(String url) {
		return url;
	}

	
	public String encodeUrl(String url) {
		return url;
	}

	
	public String encodeRedirectUrl(String url) {
		return url;
	}

	
	public void sendError(int sc, String msg) throws IOException {
		if (Log.DEBUG) {
			debug("sendError: " + sc + "  " + msg);
		}
		this.setStatus(sc, msg);
		StringEntity entity = new StringEntity(msg, null, null);
		res.setEntity(entity);
	}

	
	public void sendError(int sc) throws IOException {
		if (Log.DEBUG) {
			debug("sendError: " + sc);
		}
		this.setStatus(sc);
		StringEntity entity = new StringEntity("Error " + sc, null, null);
		res.setEntity(entity);
	}

	private void debug(String s) {
		System.out.println(s);
	}

	
	public void sendRedirect(String location) throws IOException {
		if (Log.DEBUG) {
			debug("sendRedirect: " + location);
		}
		final String msg = "Redirect: " + location;
		StringEntity body = new StringEntity(msg, null, null);
		res.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
		res.addHeader("Location", location);
		res.addHeader("Connection", "Close");
		res.setEntity(body);
	}
	
	
	public void setDateHeader(String name, long date) {
		String value = format(date);
		res.setHeader(name, value);
	}

	
	public void addDateHeader(String name, long date) {
		String value = format(date);
		res.addHeader(name, value);
	}

	
	public void setHeader(String name, String value) {
		res.setHeader(name, value);
	}

	
	public void addHeader(String name, String value) {
		res.addHeader(name, value);
	}

	
	public void setIntHeader(String name, int value) {
		res.setHeader(name, String.valueOf(value));
	}

	
	public void addIntHeader(String name, int value) {
		res.addHeader(name, String.valueOf(value));
	}

	
	public void setStatus(int sc) {
		res.setStatusCode(sc);
	}

	
	public void setStatus(int sc, String sm) {
		res.setStatusCode(sc);
		res.setReasonPhrase(sm);
	}
	
	private static final SimpleDateFormat RFC1123_DF = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
	
	private static String format(long date) {
		return RFC1123_DF.format(new Date(date));
	}
}
